<div style="padding-top: 15px; padding-bottom: 15px;">
	<div class="container">
		<a routerLink="/learn" class="btn btn-outline-dark" style="margin-top: 5px;">Back</a>
		<h2>First script</h2>

		<h3>Script object</h3>
		<p>In nunuStudio scripts are written using the javascript language, javascript is the language used for developing web pages and its a easy language to learn, no programming knowledge is required for this tutorial. But I recommend that you learn the basics of programming in javascript before moving on to the next tutorial.</p>
		<p>The script object is used to control objects using javascript code, and behave in the same way any other object does, they have a position, scale and rotations, they can have children and be used as a container.</p>
		<p>After creating a script object its possible to open the script editor by double clicking the script object in the object explorer (right side). The script editor opens in a new tab. New scripts have a basic code template with spaces to write code.</p>

		<img src="assets/learn/basics/script/script.png" class="img-big"/>

		<p>To allow easier access to program elements, scripts also have access to the following attributes</p>
		<ul>
			<li><p>self - Used to access the script object attributes (position, rotation, scale, children, etc).</p></li>
			<li><p>program - Used to access the program instance, can be used to change the current scene, access resources (getMaterialByName, getTextureByName, etc).</p></li>
			<li><p>scene - Used to acess the running scene attributes.</p></li>
			<li><p>Keyboard - provides access to keyboard input</p></li>
			<li><p>Mouse - provides access to mouse input</p></li>
		</ul>

		<h3>Script functions</h3>
		<p>There are some reserved function names, that are used by the nunuStudio runtime to run scripts code. In this tutorial we will be working only with the initialize, update and dispose methods.</p>
		<ul>
			<li><p>initialize - The initialize method is called when the scene is loaded, it is normally used to create new objects programmatically, get object from the scene, initialize variables, etc.</p></li>
			<li><p>update - Called each frame before drawing the scene into the screen, it can be used to control object, get input values, change object attributes, etc.</p></li>
			<li><p>dispose - Called when the program is being closed, should be used to cleanup objects, disconnect from data streams, etc.</p></li>
			<li><p>onMouseOver(objects) - Called when the mouse is over an object that is children of the script object, can be combined with Mouse functions to check if a object was clicked. Received an array of objects as parameter.</p></li>
			<li><p>onResize(x, y) - Called every time the program window is resized.</p></li>
			<li><p>onAppData(data) - Used to receive data from the host page, data is received as argument.</p></li>
		</ul>

		<h3>Moving an object</h3>
		<p>To move an object we start by attaching that object as a children of the script object, we can do that by dragging the desired object to the script object, in this tutorial we will use the cube object on the default scene. Lets start by testing the following code</p>
		<pre><code class="hljs javascript">function initialize()
{{'{'}}
self.position.x += 2;
{{'}'}}</code></pre>
		<p>This code will move the cube 2 points in the x axis when the program is started, but, after  the object is moved it stays in place.</p>
		<p>To animate an object we can instead move our code to the update method, instead of playing with the object position lets try to change now its rotation by testing the following code.</p>
		<pre><code class="hljs javascript">function update()
{{'{'}}
self.rotation.y += 0.01;
{{'}'}}</code></pre>
		<p>If everything works as expected you should see the following animation. To try this example in the editor you can download the <a class="underline" href="rotate.nsp">project file</a> or open it on the <a class="underline" href="https://www.nunustudio.org/editor?isp=https://nunustudio.org/learn/basics/02_script/rotate.nsp">Web Editor</a>.</p>

		<app-viewer fname="assets/learn/basics/script/rotate.nsp"></app-viewer>

		<h3>Keyboard and Mouse input</h3>
		<p>Its possible to use the keyboard and mouse to move objects around. This can be done using the Keyboard and Mouse objects inside scripts. The code bellow rotates an object in the y axis using the mouse delta, and moves the object aroud using keyboard arrow keys.</p>
		<pre><code class="hljs javascript">function update()
{{'{'}}
self.rotation.y += Mouse.delta.x * 0.01;

if(Keyboard.keyPressed(Keyboard.LEFT))
{{'{'}}
	self.position.x -= 0.1;
{{'}'}}
if(Keyboard.keyPressed(Keyboard.RIGHT))
{{'{'}}
	self.position.x += 0.1;
{{'}'}}
{{'}'}}</code></pre>
		<p>If everything works as expected you should be able to move the cube around using the keyboard arrow keys and rotate it using the mouse as shown bellow. To try this example in the editor you can download the <a class="underline" href="input.nsp">project file</a> or open it on the <a class="underline" href="https://www.nunustudio.org/editor?isp=https://nunustudio.org/learn/basics/02_script/input.nsp">Web Editor</a>.</p>

		<app-viewer fname="assets/learn/basics/script/input.nsp"></app-viewer>

		<h3>Getting objects</h3>
		<p>Its possible to access other objects and resources with scripts, in the example bellow we use the scene.getObjectByName() method to get an object by its name (in this case an object named box), if multiple objects with the same name are found the first one is returned.</p>
		<p>Resources are stored in the program, similarly the methods program.getMaterialByName(), program.getTextureByName(), etc can be used to get them, (check the ResourceManager API documentation page for more information).</p>
		<pre><code class="hljs language-javascript">var object;

function initialize()
{{'{'}}
object = scene.getObjectByName("box");
{{'}'}}

function update()
{{'{'}}
object.rotation.y += 0.01;
{{'}'}}</code></pre>

		<p>Another way to access objects its by navigating the tree structure, every object has a parent and children, the parent points to the object above and children is an array of all objects bellow.</p>
		<p>In the following code we get the first object placed inside the scripts and make it rotate without rotating the script itself. Be careful when accessing children or parent objects directly since it depends on the object placement in the project a change can break the code.</p>
		<pre><code class="hljs javascript">var object;

function initialize()
{{'{'}}
object = self.children[0];
{{'}'}}

function update()
{{'{'}}
object.rotation.y += 0.01;
{{'}'}}</code></pre>

		<h3>Switch scenes</h3>
		<p>Its possible to create multiple scenes in the editor and switch between them using scripts. Scenes can be accessed from the program variable accessible to all scripts. The setScene() method discards the current scene and loads a new scene it receives the scene name or the scene object (stored in the program.scenes array) as argument</p>
		<p>The code bellow can be used to switch to the "scene2" after the W key is pressed on the keyboard. To return to the original scene the scene2 has to implement a similar logic there is no automatic scene navigation flow.</p>
		<pre><code class="hljs javascript">function update(delta)
{{'{'}}
if(Keyboard.keyPressed(Keyboard.W))
{{'{'}}
	program.setScene("scene2");
{{'}'}}
{{'}'}}</code></pre>

		<h3>Object attributes</h3>
		<p>The self pointer in the script object can be used to store aditional attributes that can be accessed by other scripts. Attributes can also be stored into objects be carefull to avoid collisions with the already existing ones provided by the nunuStudio API.</p>
		<p>In the example bellow we create a counter variable attached to the script object and a increaseCounter function that can be accessed and called by other scripts.</p>
		<pre><code class="hljs javascript">self.counter = 0;

self.increaseCounter = function()
{{'{'}}
self.counter++;
{{'}'}}</code></pre>

		<h3>DOM Elements</h3>
		<p>Its possible to attach dom elements to the program created. To do this we can use the division property of the program that gives us access to a DOM division element (parent of the canvas element used to draw content) where we can add HTML elements.</p>
		<p>The example below demonstrates how to create a new red division with size 50 x 50 add it to the program and remove it when the program is being closed.</p>
		<pre><code class="hljs javascript">var element = document.createElement("div");
element.style.width = "100px";
element.style.height = "100px";
element.style.position = "absolute";
element.style.top = "0px";
element.style.backgroundColor = "#FF0000";

function initialize()
{{'{'}}
	program.division.appendChild(element);
{{'}'}}

function dispose()
{{'{'}}
	program.division.removeChild(element);
{{'}'}}</code></pre>

		<h3>Libraries</h3>
		<p>To add external libraries to your script first you need to import the js file into the project, you can just simply drag the JS source file into the asset explorer or go to Import/Text and select the js file.</p>

		<img src="assets/learn/basics/script/include.jpg" class="img-normal"/>

		<p>After importing the file into the project you can now include it in your script using the include(name) method preferabily at the top of your code. There are multiple include modes available by default the script objects use Evaluate mode the library is evaluated and executed in your script context, the Append mode appends the code of your library on top of your script code, this makes compiling a bit slower but local defined code becomes available to your script. Script mode can be selected in the Script object panel.</p>

		<pre><code class="hljs javascript">include("moment.min.js"); //https://momentjs.com/
// include("https://momentjs.com/downloads/moment.min.js");

var date, hour;

function initialize()
{{'{'}}
date = program.getObjectByName("date");
date.setText(moment().format("MMM Do YY"));

hour = program.getObjectByName("hour");
{{'}'}}

function update()
{{'{'}}
var text = moment().format('LTS');
if(text !== hour.text)
{{'{'}}
	hour.setText(text);
{{'}'}}
{{'}'}}

function dispose()
{{'{'}}
delete moment;
{{'}'}}
</code></pre>

		<p>The code above demonstrates how to use moment.js to display date and time on a text object. The library is available for free at https://momentjs.com/. To try this example in the editor you can download the <a class="underline" href="include.nsp">project file</a> or open it on the <a class="underline" href="https://www.nunustudio.org/editor?isp=https://nunustudio.org/learn/basics/02_script/include.nsp">Web Editor</a>.</p>

		<app-viewer fname="assets/learn/basics/script/include.nsp"></app-viewer>
	</div>
</div>|
